﻿//Quote.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.BusinessEntities
{
	using System;
	using System.Collections.Generic;
	using System.ComponentModel;
	using System.Runtime.Serialization;
	using System.Xml.Serialization;
	using NetDataContract = System.Runtime.Serialization.DataContractAttribute;

	using Ecng.ComponentModel;
	using Ecng.Common;
	using Ecng.Serialization;

	/// <summary>
	/// Котировка стакана, представляющая бид или оффер.
	/// </summary>
	[Serializable]
	[NetDataContract]
	[Ignore(FieldName = "IsDisposed")]
	[DisplayName("Котировка")]
	[Description("Котировка стакана, представляющая бид или оффер.")]
	public class Quote : Equatable<Quote>, IExtendableEntity
	{
		/// <summary>
		/// Создать <see cref="Quote"/>.
		/// </summary>
		public Quote()
		{
		}

		/// <summary>
		/// Создать <see cref="Quote"/>
		/// </summary>
		/// <param name="security">Инструмент, по которому получена котировка.</param>
		/// <param name="price">Цена котировки.</param>
		/// <param name="volume">Количество лотов.</param>
		/// <param name="direction">Направление (покупка или продажа).</param>
		public Quote(Security security, decimal price, decimal volume, OrderDirections direction)
		{
			_security = security;
			_price = price;
			_volume = volume;
			_direction = direction;
		}

		/// <summary>
		/// Цена в единицах Security.MinStepPrice (используется для оптимизации)
		/// </summary>
		public int PriceIndex;


		private Security _security;

		/// <summary>
		/// Инструмент, по которому получена котировка.
		/// </summary>
		[Ignore]
		[XmlIgnore]
		[Browsable(false)]
		public Security Security
		{
			get { return _security; }  
			set { _security = value; }
		}

		private decimal _price;

		/// <summary>
		/// Цена котировки.
		/// </summary>
		[DataMember]
		[DisplayName("Цена")]
		[Description("Цена котировки.")]
		[Category("Основные")]
		public decimal Price
		{
			get { return _price; }
			set { _price = value; }
		}

		private decimal _volume;

		/// <summary>
		/// Количество лотов.
		/// </summary>
		[DataMember]
		[DisplayName("Объем")]
		[Description("Количество лотов.")]
		[Category("Основные")]
		public decimal Volume
		{
			get { return _volume; }
			set { _volume = value; }
		}

		private OrderDirections _direction;

		/// <summary>
		/// Направление (покупка или продажа).
		/// </summary>
		[DataMember]
		[DisplayName("Направление")]
		[Description("Направление (покупка или продажа).")]
		[Category("Основные")]
		public OrderDirections OrderDirection
		{
			get { return _direction; }
			set { _direction = value; }
		}

		[field: NonSerialized]
		private IDictionary<object, object> _extensionInfo;

		/// <summary>
		/// Расширенная информация по котировке.
		/// </summary>
		/// <remarks>
		/// Необходима в случае хранения в программе дополнительной информации, ассоциированной с котировкой.
		/// Например, количество собственных контрактов в стакане, сумму лучшей покупки-продажи.
		/// </remarks>
		[Ignore]
		[XmlIgnore]
		[DisplayName("Расширенная информация")]
		[Description("Необходима в случае хранения в программе дополнительной информации, ассоциированной с котировкой.")]
		[Category("Основные")]
		public IDictionary<object, object> ExtensionInfo
		{
			get { return _extensionInfo; }
			set { _extensionInfo = value; }
		}

		/// <summary>
		/// Создать копию объекта <see cref="Quote" />.
		/// </summary>
		/// <returns>Копия.</returns>
		public override Quote Clone()
		{
			return new Quote(_security, _price, _volume, _direction)
			{
				ExtensionInfo = ExtensionInfo,
				PriceIndex = PriceIndex
			};
		}

		/// <summary>
		/// Сравнить две котировки на эквивалентность.
		/// </summary>
		/// <param name="other">Другая котировки, с которой необходимо сравнивать.</param>
		/// <returns>true, если другая котировки равна текущей, иначе false.</returns>
		protected override bool OnEquals(Quote other)
		{
			return
				Security == other.Security &&
				OrderDirection == other.OrderDirection &&
				Price == other.Price;// &&
				//Volume == other.Volume;
		}

		/// <summary>
		/// Рассчитать хеш-код объекта <see cref="Quote" />.
		/// </summary>
		/// <returns>Хеш-код.</returns>
		public override int GetHashCode()
		{
			return (Security != null ? Security.GetHashCode() : 0) ^ OrderDirection.GetHashCode() ^ Price.GetHashCode();// ^ Volume.GetHashCode();
		}

		/// <summary>
		/// Получить строковое представление.
		/// </summary>
		/// <returns>Строковое представление.</returns>
		public override string ToString()
		{
			return "{0} {1} {2}".Put(OrderDirection == OrderDirections.Buy ? "Бид" : "Оффер", Price, Volume);
		}

		[field: NonSerialized]
		private PropertyChangedEventHandler _propertyChanged;

		event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
		{
			add { _propertyChanged += value; }
			remove { _propertyChanged -= value; }
		}

		void INotifyPropertyChangedEx.NotifyPropertyChanged(string info)
		{
			_propertyChanged.SafeInvoke(this, info);
		}
	}
}
